﻿using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using NLog;
using NLog.Config;
using NLog.Targets;
using PortCommunicate.LogEntries;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using NLog.LayoutRenderers;

namespace PortCommunicate.ViewModels
{
    public partial class LogViewModel : ObservableObject
    {
        private readonly WpfLogTarget _logTarget;

        private readonly Logger logger = LogManager.GetCurrentClassLogger();

        [ObservableProperty]
        public ObservableCollection<LogEntry> logs = new ObservableCollection<LogEntry>();

        public LogViewModel()
        {
            // 初始化自定义NLog目标  
            _logTarget = new WpfLogTarget();

            //Linq注册自定义LayoutRenderer 
            LogManager.Setup().SetupExtensions(ext =>ext.RegisterLayoutRenderer
            (
                "currentRWType",logEvent => Mediator.currentRWType?.ToString() ?? "unknown"
            ));

            // 注册自定义LayoutRenderer  
            string startupTime = DateTime.Now.ToString("yyyy-MM-dd-HH:mm:ss");

            var config = new LoggingConfiguration();
            var fileLogConfig = new FileTarget()
            {
                Name = "logs",
                FileName = "${basedir}/logs/" + startupTime + ".log",
                Layout = "${longdate}-[${currentRWType}]-[${level}] ${message}  ${exception}", // 使用自定义变量  
                ArchiveFileName = "{basedir}/logs/archives/log.{#}.log",
                ArchiveEvery = NLog.Targets.FileArchivePeriod.Day,
                CreateDirs = true,
            };
            config.AddTarget(fileLogConfig);
            config.AddRule(LogLevel.Trace, LogLevel.Fatal, fileLogConfig);
            config.AddTarget("wpfTarget", _logTarget);
            config.AddRuleForAllLevels(_logTarget); // 记录所有级别的日志  
            LogManager.Configuration = config;

            logger.Info("程序启动");
            _logTarget.LogEntries.CollectionChanged += LogEntries_CollectionChanged;
        }

        public event Action ScrollToBottomRequested;

        private void LogEntries_CollectionChanged(object? sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            // NewItems 属性只在特定的集合变更类型下有值,添加替换  
            if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add && e.NewItems != null)
            {
                foreach (LogEntry entry in e.NewItems)
                {
                    Logs.Add(entry);// LogEntries中的元素添加到Logs中  
                }
                // ScrollToBottomRequested?.Invoke();  
            }
        }

        [RelayCommand]
        public void SelectInfo()
        {
            LogFilter("Info");
        }

        [RelayCommand]
        public void SelectWarning()
        {
            LogFilter("Warn");
        }

        [RelayCommand]
        public void SelectError()
        {
            LogFilter("Error");
        }

        // 清除日志  
        [RelayCommand]
        public void ClearLogs()
        {
            Logs.Clear();
            _logTarget.LogEntries.Clear();
        }

        // 打开日志路径  
        [RelayCommand]
        public void OpenLogs()
        {
            try
            {
                string filePath = Path.Combine(Directory.GetCurrentDirectory(), "logs");
                Process.Start(new ProcessStartInfo
                {
                    FileName = filePath,
                    UseShellExecute = true
                });
            }
            catch (Exception ex)
            {
                logger.Error(ex);
            }
        }

        private void LogFilter(string level)
        {
            Logs.Clear();
            foreach (var entry in _logTarget.LogEntries)
            {
                if (entry.Level == level && _logTarget.LogEntries.Count != 0)
                {
                    Logs.Add(entry);
                }
            }
        }
    }
}
